﻿#include "TCP.h"
#include<iostream>
#ifdef _WIN32
//win32或win64
#define _CRT_SECURE_NO_DEPRECATE 
#include <WinSock2.h>
#pragma comment(lib,"ws2_32.lib")
#pragma warning(disable : 4996)//关闭警告
#define ETYPE  Windows
#elif __linux__
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/epoll.h>
#include <netdb.h>
#define ETYPE  Linux
#endif
#include<string.h>
TCP::TCP()
	:m_sockaddr(new sockaddr_in)
{
}
TCP::TCP(const std::string ip, const unsigned int port)
	:m_sockaddr(new sockaddr_in)
{
	socket(ip, port, SOCK_STREAM);
}
TCP::TCP(const std::string ip, const unsigned int port, const size_t listenNum)
	:m_sockaddr(new sockaddr_in)
{
	socket(ip, port, SOCK_STREAM);
	bind();
	//监听
	int r = ::listen(m_socket, listenNum);
	if (-1 == r)
	{
		printf("监听失败:%m\n");
		return ;
	}
}
TCP::~TCP()
{
	if (m_sockaddr != nullptr)
		delete m_sockaddr;
}
const int TCP::socket(const std::string ip, const unsigned int port)
{
	return socket(ip, port, SOCK_STREAM);
}
const int TCP::socket(const std::string ip, const unsigned int port, const int type)
{
#ifdef _WIN32
	WSADATA wsadata;
	if (WSAEINVAL == WSAStartup(MAKEWORD(2, 2), &wsadata))printf("选择版本失败:%m\n"), exit(-1);
#endif
#ifdef _WIN32
	m_socket = ::socket(AF_INET, type, IPPROTO_TCP);
#else
	m_socket = ::socket(AF_INET, type, 0);
#endif	
	if (0 > m_socket)return m_socket;
	//通过域名获取ip地址
	hostent* hent = gethostbyname(ip.c_str());
	if (!hent) {std::cout << "域名解析失败" << std::endl; return -1;};
	//sockaddr_in Sockaddr;
	memcpy(&m_sockaddr->sin_addr, hent->h_addr, sizeof(in_addr));
	//协议地址族
	m_sockaddr->sin_family = AF_INET;//和socket函数第一个参数一致
	m_sockaddr->sin_port = htons(port)/*htons(atoi(argv[2]))*/;//端口号
}
const int TCP::bind()
{
	int r = ::bind(m_socket, (struct sockaddr*)m_sockaddr, sizeof(*m_sockaddr));
	if (-1 == r)
	{
		printf("绑定失败:%m\n");
	}
	return r;
}

const int TCP::connect()
{
	//连接服务器
	int ret = ::connect(m_socket, (struct sockaddr*)m_sockaddr, sizeof(*m_sockaddr));
	if (ret < 0)
	{
		printf("connect连接服务器失败\n");
	}
	return ret;
}

const int TCP::accept(sockaddr_in* Sockaddr)
{
	//接受客户端连接
#ifdef __linux__
	unsigned int size = sizeof(*Sockaddr);
#elif _WIN32
	int size = sizeof(*Sockaddr);
#endif
	int ret = ::accept(m_socket, (sockaddr*)Sockaddr, &size);
	if (-1 == ret)
	{
		printf("接受客户端连接失败:%m\n");
	}
	return ret;
}



const int TCP::send(const char* buf, const int len)
{
	return send(m_socket, buf, len);
}

const int TCP::send(const int socket, const char* buf, const int len)
{
	return ::send(socket, buf, len, 0);
}

const int TCP::recv(char* buf, const int len)
{
	return recv(m_socket, buf, len);
}

const int TCP::recv(const int socket, char* buf, const int len)
{
	return ::recv(socket, buf, len, 0);
}

const int TCP::close(const int socket)
{
#ifdef __linux__
	return ::close(socket);
#elif _WIN32
	return closesocket(socket);//关闭
	//WSACleanup();//释放资源
#endif
}

const int TCP::close()
{
	return close(m_socket);
}

const int TCP::setSendBuff(const int socket,const int len)
{
	//发送缓冲区
	return setsockopt(socket, SOL_SOCKET, SO_SNDBUF, (const char*)&len, sizeof(const int));
}

const int TCP::setSendBuff(const int len)
{
	return setSendBuff(m_socket,len);
}

const int TCP::setRecvBuff(const int socket,const int len)
{
	// 接收缓冲区
	return setsockopt(socket, SOL_SOCKET, SO_RCVBUF, (const char*)&len, sizeof(const int));
}

const int TCP::setRecvBuff(const int len)
{
	return setRecvBuff(m_socket,len);
}
